#include <iostream>
#include <string>
using namespace std;

// Scenario: Inventory Management System Template Class
template<class T>
class Warehouse {
private:
    T* items;       // Array for inventory items (template type)
    int capacity;   // Maximum capacity of the warehouse
    int count;      // Current number of items

public:
    // Constructor - Initialize the warehouse
    Warehouse(int maxSize) : capacity(maxSize), count(0) {
        items = new T[capacity];
        cout << "Constructor called, created warehouse with capacity " << maxSize << endl;
    }

    // Copy Constructor - Deep copy the warehouse
    Warehouse(const Warehouse& other) : capacity(other.capacity), count(other.count) {
        items = new T[capacity];
        for(int i = 0; i < count; ++i) {
            items[i] = other.items[i];
        }
        cout << "Copy constructor called, deep copied warehouse" << endl;
    }

    // Destructor - Release memory
    ~Warehouse() {
        delete[] items;
        cout << "Destructor called, released warehouse memory" << endl;
    }

    // Overload += operator to add items
    Warehouse& operator+=(const T& newItem) {
        if(count < capacity) {
            items[count++] = newItem;
            cout << "Added item: " << newItem << endl;
        } else {
            cout << "Warehouse is full, cannot add more items" << endl;
        }
        return *this;
    }

    // Overload + operator to merge two warehouses
    Warehouse operator+(const Warehouse& other) {
        Warehouse newWarehouse(this->capacity + other.capacity);
        for(int i = 0; i < this->count; ++i) {
            newWarehouse += this->items[i];
        }
        for(int i = 0; i < other.count; ++i) {
            newWarehouse += other.items[i];
        }
        cout << "Merged two warehouses, new capacity: " << newWarehouse.capacity << endl;
        return newWarehouse;
    }

    // Display inventory
    void display() const {
        cout << "Current inventory (total " << count << " items): ";
        for(int i = 0; i < count; ++i) {
            cout << items[i] << " ";
        }
        cout << endl;
    }
};

int main() {
    // Create a warehouse for integers (demonstrate templates)
    Warehouse<int> electronics(3);
    electronics += 1001; // Item ID
    electronics += 1002;
    electronics += 1003;
    
    // Test full warehouse
    electronics += 1004; // Should display "Warehouse is full"

    // Create a copy of the warehouse (demonstrate copy constructor)
    Warehouse<int> backup = electronics;
    backup.display();

    // Create a warehouse for strings (demonstrate template generics)
    Warehouse<string> books(2);
    books += "C++ Primer";
    books += "Design Patterns";

    // Merge warehouses (demonstrate operator overloading)
    Warehouse<int> megaWarehouse = electronics + backup;
    megaWarehouse.display();

    return 0;
}